home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 20 / Cream of the Crop 20 (Terry Blount) (1996).iso / program / freeli20.zip / progs / 3xp1.asm next >
Assembly Source File  |  1996-07-01  |  3KB  |  102 lines

  1. ; 3X+1 solver using FREELIB
  2.  
  3. Ideal
  4.  
  5. Public      main
  6. Extrn       startup:near
  7.  
  8. Macro       lcall p,a,b,c,d,e,f,g,h ;; library call
  9.  
  10.             ifnb <a>
  11.               push a                ;; if args, push first arg
  12.               lcall p,b,c,d,e,f,g,h ;; and recurse . . .
  13.             else
  14.               extrn p:near          ;; declare procedure
  15.               call p                ;; call procedure
  16.             endif
  17.  
  18. EndM
  19.  
  20. Model Tiny
  21. CodeSeg
  22. P186
  23. Org 100h
  24.  
  25. Start:      jmp startup
  26.  
  27. ;****************** Data Section
  28.  
  29. rtn         db 13,0
  30. buf         db 15 dup(0)
  31. BadFmt      db 13,10,13,10,'Number %d went out of range',13,10,0
  32. BadArg      dw ?,?
  33. OkStr       db 'No anomaly found',0
  34.  
  35. ;****************** 'main' procedure
  36.  
  37. Proc        main
  38.  
  39.             mov ax,3                ;Start with 3
  40.             xor dx,dx
  41.  
  42. MLoop:      pusha                   ;Save all registers
  43.             mov bp,dx               ;CX:BX:AX = number
  44.             mov bx,dx               ;BP = threshold
  45.             xor cx,cx
  46.  
  47. CLoop:      test cx,cx              ;Out of range, quit
  48.             jl Quit
  49.             jnz CCont
  50.             cmp bx,bp               ;CX = 0, check if less
  51.             jb CDone                ;Quit if less than the
  52.             test bx,bx              ;original number
  53.             jz CDone
  54.  
  55. CCont:      test ax,1               ;Check for odd
  56.             jz CSkip
  57.  
  58.             mov dx,ax               ;N = 3 * N + 1
  59.             add ax,ax
  60.             mov si,bx
  61.             adc bx,bx
  62.             mov di,cx
  63.             adc cx,cx
  64.             add ax,dx
  65.             adc bx,si
  66.             adc cx,di
  67.             add ax,1
  68.             adc bx,0
  69.             adc cx,0
  70.  
  71. CSkip:      shr cx,1                ;N = N / 2
  72.             rcr bx,1
  73.             rcr ax,1
  74.             jmp CLoop               ;Loop back
  75.  
  76. CDone:      popa                    ;Restore all registers
  77.  
  78.             cmp ax,3                ;Low word = 3, display
  79.             jne MSkip
  80.  
  81.             lcall ltoa dx,ax,offset(buf)  ;Display the number
  82.             lcall puts offset(buf)
  83.             lcall puts offset(rtn)
  84.  
  85. MSkip:      add ax,4                ;Add 4 (increment)
  86.             adc dx,0
  87.             cmp dx,230              ;Loop while < 15 million
  88.             jb MLoop
  89.  
  90.             lcall puts offset(OkStr)      ;Print OK message
  91.             ret                     ;Return
  92.  
  93. Quit:       popa                    ;Overflowed...
  94.             mov [BadArg],ax         ;Print out-of-range message
  95.             mov [BadArg+2],dx
  96.             lcall printf offset(BadFmt),offset(BadArg)
  97.             ret                     ;Return
  98.  
  99. EndP        main
  100.  
  101. End Start
  102.